package com.rtf.framework.dao.rule.levelpath;

import com.rtf.framework.common.exception.AppException;
import com.rtf.framework.common.support.dao.handler.AppBaseDataHandlerAdaptor;
import com.rtf.framework.common.util.UtilCollection;
import com.rtf.framework.common.util.UtilTree;
import org.springframework.beans.factory.annotation.Autowired;

import javax.persistence.Table;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class LevelPathDataHandler extends AppBaseDataHandlerAdaptor {

    @Autowired
    private LevelPathRecordDao levelPathRecordDao;

    @Override
    public boolean support(Class<?> entityClass) {
        return LevelPathRecord.class.isAssignableFrom(entityClass);
    }

    public <T> int updateLevelInfo(T entity) {
        Table tableAnno = entity.getClass().getAnnotation(Table.class);
        if (tableAnno == null) {
            throw new AppException("当前类必须是jpa管理的类");
        }

        LevelPathRecord levelPathRecord = (LevelPathRecord) entity;

        if (levelPathRecord.getParentId() == null || levelPathRecord.getParentId() == 0) {
            //对于空的父节点记录，默认为0
            levelPathRecord.setParentId(0L);
            levelPathRecord.setLevelPath(levelPathRecord.getId().toString());
            levelPathRecord.setLevelName(levelPathRecord.getName().trim());
        } else {
            String parentLevelPath = "";
            String parentLevelName = "";
            Map<String, String> parentItem = levelPathRecordDao.queryById(tableAnno.name(), levelPathRecord.getParentId());
            if (parentItem != null) {
                parentLevelPath = parentItem.get("level_path");
                parentLevelName = parentItem.get("level_name");
            }
            levelPathRecord.setLevelPath(parentLevelPath + ";" + levelPathRecord.getId().toString());
            levelPathRecord.setLevelName((parentLevelName + ";" + levelPathRecord.getName()).trim());
        }

        //实际更新的次数
        int updateNum = levelPathRecordDao.updateLevelPath(tableAnno.name(), levelPathRecord.getId().toString(),
                levelPathRecord.getLevelPath(), levelPathRecord.getLevelName());

        return updateNum;
    }

    @Override
    public <T> T postSaveHandler(T entity) {
        updateLevelInfo(entity);
        return entity;
    }

    @Override
    public <T> T preUpdateHandler(T entity, Collection<String> updateFields) {
        super.preUpdateHandler(entity, updateFields);

        int updateNum = updateLevelInfo(entity);
        //更新下级的路径
        if (updateNum > 0) {
            Table tableAnno = entity.getClass().getAnnotation(Table.class);
            if (tableAnno == null) {
                throw new AppException("当前类必须是jpa管理的类");
            }

            LevelPathRecord levelPathRecord = (LevelPathRecord) entity;

            //查询下级所有的节点
            List<Map<String, Object>> subItems = levelPathRecordDao.querySubById(tableAnno.name(), levelPathRecord.getId());
            if (subItems == null || UtilCollection.isEmpty(subItems)) {
                return entity;
            }

            //将下级节点转换为树结构；由于树结构使用的原有数据的引用，因此会直接更新原有Map的内容。
            List<Map<String, Object>> subItemTree = UtilTree.getTreeData(subItems, "id", "parent_id", "children", false);
            calculateSubLevelInfo(subItemTree, levelPathRecord.getLevelPath(), levelPathRecord.getLevelName());

            //更新所有下级节点的层级
            for (Map<String, Object> subItem : subItems) {
                levelPathRecordDao.updateLevelPath(tableAnno.name(), subItem.get("id").toString(),
                        subItem.get("level_path").toString(), subItem.get("level_name").toString());
            }
        }

        return entity;
    }

    /**
     * 计算下级层次配置
     *
     * @param subItemTree
     */
    public void calculateSubLevelInfo(List<Map<String, Object>> subItemTree, String parentLevelPath, String parentLevelName) {
        if (subItemTree == null || UtilCollection.isEmpty(subItemTree)) {
            return;
        }
        for (Map<String, Object> subItem : subItemTree) {
            String itemLevelPath = parentLevelPath + ";" + subItem.get("id");
            String itemLevelName = parentLevelName + ";" + subItem.get("name");
            subItem.put("level_path", itemLevelPath);
            subItem.put("level_name", itemLevelName);
            // 计算当前节点的下级
            calculateSubLevelInfo(subItem.get("children") != null ? (List<Map<String, Object>>) subItem.get("children") : null,
                    itemLevelPath, itemLevelName);
        }

    }

    @Override
    public <ID> void preDeleteHandler(ID id, Class<?> domainClass) {
        Table tableAnno = domainClass.getAnnotation(Table.class);
        if (tableAnno == null) {
            throw new AppException("当前类必须是jpa管理的类");
        }
        int subItemNum = levelPathRecordDao.subNumByLevel(tableAnno.name(), id.toString());
        if (subItemNum > 0) {
            throw new AppException("存在关联下级，不能删除。");
        }
        super.preDeleteHandler(id, domainClass);
    }
}
